#include <machine/asmdefs.h>

ASM_HEADER

FNDEFN_BEGIN(correlation_asm)

        stwul           %r1,%r1,-96             # set stack pointer
        lr              %vr1,%r10,0             ||       addil           %r12,%r1,8   # copy stack pointer
        lr              %vr5,%r10,32

        lr              %vr2,%r8,0              ||       lir             %r14,15    # set first loop counter to 15 iterations
        lrr             %vr3,%r8,32             ||       lir             %r15,5     # set second loop counter to 5 iterations
        lr              %vr6,%r8,32             ||       ctsr            %r14,5
        lrr             %vr7,%r8,64             ||       lir             %r13,0

        /* compute dot products of I with Barker code */

        /* first 16 outputs */
LOOP_CORR_INNER_A:
        rmulreds1r      0,%ac0,%vr2,%vr1
        rmulreds1n      %ac0,%vr6,%vr5          ||       loop		0,%lc1,LOOP_CORR_INNER_A

        rmulreds1r      0,%ac0,%vr2,%vr1        ||       lrr            %vr3,%r8,64
        rmulreds1n      %ac0,%vr6,%vr5          ||       lrr            %vr7,%r8,96

        rshift          %vr0,%ac0,0             ||       ctsr           %r15,5

        /* next 6 outputs */
LOOP_CORR_INNER_B:
        rmulreds1r      1,%ac0,%vr2,%vr1
        rmulreds1n      %ac0,%vr6,%vr5          ||       loop		0,%lc1,LOOP_CORR_INNER_B

        rmulreds1r      1,%ac0,%vr2,%vr1        ||       lr             %vr2,%r9,0  ||       ctsr            %r13,73    # set ac1 (low) to zero
        rmulreds1n      %ac0,%vr6,%vr5          ||       lrr            %vr3,%r9,32 ||       ctsr            %r13,77    # set ac1 (high) to zero

        /* shift vector 16-6=10 times */
        str             %vr0,%r12,0             ||       rshift         %vr4,%ac0,0
        rshift          %vr4,%ac1,6             ||       lr             %vr6,%r9,32
        rshift          %vr4,%ac1,6             ||       lrr            %vr7,%r9,64
        rshift          %vr4,%ac1,4             ||       ctsr           %r14,5
        str             %vr4,%r12,32

        /* compute dot product of Q with Barker code */

        /* first 16 outputs */
LOOP_CORR_INNER_C:
        rmulreds1r      0,%ac0,%vr2,%vr1
        rmulreds1n      %ac0,%vr6,%vr5          ||       loop		0,%lc1,LOOP_CORR_INNER_C

        rmulreds1r      0,%ac0,%vr2,%vr1        ||       lrr            %vr3,%r9,64
        rmulreds1n      %ac0,%vr6,%vr5          ||       lrr            %vr7,%r9,96

        rshift          %vr0,%ac0,0             ||       ctsr           %r15,5

        /* next 6 outputs */
LOOP_CORR_INNER_D:
        rmulreds1r      1,%ac0,%vr2,%vr1
        rmulreds1n      %ac0,%vr6,%vr5          ||       loop		0,%lc1,LOOP_CORR_INNER_D

        rmulreds1r      1,%ac0,%vr2,%vr1        ||       lr             %vr1,%r12,0
        rmulreds1n      %ac0,%vr6,%vr5          ||       lr             %vr5,%r12,32

        /* shift vector 16-6=10 times */
        rshift          %vr4,%ac0,0
        rshift          %vr4,%ac1,6
        rshift          %vr4,%ac1,6
        rshift          %vr4,%ac1,4

        /* compute square sum of correlations */
        rmuls           %vr1,%vr1,%vr1
        rmacs           %vr1,%vr0,%vr0
        rmuls           %vr5,%vr5,%vr5          ||      ctsr        %r13,0x45       # set mpos to zero
        rmacs           %vr5,%vr4,%vr4          ||      ctsr        %r13,0x44       # set mcount to zero

        /* search for max val */
        rsearchmax      %ac1,%vr1
        rsearchmax      %ac1,%vr5

        cfsr            %r15,0x45               # get mpos
        stw             %r15,%r11,0             ||      cfsr        %r8,73     # store mpos, get maxval
        shril           %r8,%r8,16              # shift maxval right by 16
        lw              %r1,%r1,0               ||      ji          %jt0,8

FNDEFN_END(correlation_asm)
